#include <WiFi.h>

const char *ssid = "";
const char *password = "";

const char *validUser = "admin";   // NUT 用户名
const char *validPass = "ha12345"; // NUT 密码

WiFiServer nutServer(3493);
const int MAX_CLIENTS = 5; // 允许的最大客户端连接数
WiFiClient clients[MAX_CLIENTS];

bool isAuthenticated[MAX_CLIENTS] = {false};    // 每个客户端的认证状态
bool authRequired[MAX_CLIENTS] = {false};       // 每个客户端的认证模式状态
unsigned long authStartTime[MAX_CLIENTS] = {0}; // 记录认证开始时间

String ups_mfr = "MUYAN-DIY";                   /*厂商*/
String ups_model = "ESP32-NUT-UPS";             /*型号*/
String ups_power_nominal = "500";               /*标称功率*/
int ups_charge = 90;                            /*电池电量*/
String ups_charge_low = "30";                   // 电池电量低设定点
int ups_runtime = 360;                         // 电池可运行时间
float ups_voltage = 16.8;                      // 电池电压
String ups_type = "Li-ion";                     // 电池类型 PbAc
String ups_driver_name = "usbhid-ups";          // 驱动名称
String ups_driver_parameter_port = "auto";      // 驱动参数端口
String ups_driver_version = "2.2.0";            // 驱动版本
String ups_driver_version_data = "MGE HID 0.7"; // 驱动版本数据
String ups_driver_version_internal = "0.23";    // 驱动版本内部
float ups_input_frequency = 49.0;               // 输入频率
float ups_input_transfer_high = 294.0;          // 高压转移
float ups_input_transfer_low = 160.0;           // 低压转移
float ups_input_voltage = 230.0;                // 输入电压
float ups_output_current = 0.00;                // 输出电流
float ups_output_frequency = 49.0;              // 输出频率
float ups_output_voltage = 230.0;               // 输出电压
float ups_output_voltage_nominal = 230.0;       // 标称输出电压
String ups_device_mfr = "MUYAN-DIY";            // 制造商信息
String ups_device_model = "ESP32-NUT-UPS";      // 设备型号
String ups_device_type = "ups";                 // 设备类型
String ups_outlet_id = "0";                     //
String ups_outlet_switchable = "yes";           //
int ups_delay_shutdown = -1;                    // UPS关机延时
int ups_delay_start = -10;                      // 加载重启延时
int ups_load = 10;                              // 负载
String ups_serial = "Blank";                // 序列号
String ups_status = "OL CHRG";                  // UPS 状态（OL：在线 CHRG：充电 LB：电量不足 ）
int ups_test_interval = 604800;                 // 自检间隔
String ups_test_result = "Done and passed";     // 自检结果 Done and OK

void setup()
{
    Serial.begin(115200);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nWiFi connected");

    nutServer.begin();
}

void nut_handleClient(int clientIndex)
{
    WiFiClient &client = clients[clientIndex];

    while (client.available())
    {
        String request = client.readStringUntil('\n');
        request.trim();

        Serial.print("Received request: ");
        Serial.println(request);

        if (request.startsWith("USERNAME "))
        {
            String receivedUser = request.substring(9);
            if (receivedUser == validUser)
            {
                authRequired[clientIndex] = true; // 进入验证模式
                client.println("OK");
            }
            else
            {
                client.println("ERR ACCESS-DENIED");
                client.stop();
            }
        }
        else if (request.startsWith("PASSWORD "))
        {
            if (!authRequired[clientIndex])
            {
                client.println("ERR UNKNOWN-COMMAND");
                return;
            }

            String receivedPass = request.substring(9);
            if (receivedPass == validPass)
            {
                isAuthenticated[clientIndex] = true;
                client.println("OK");
            }
            else
            {
                client.println("ERR ACCESS-DENIED");
                client.stop();
            }
        }
        else if (!authRequired[clientIndex] || isAuthenticated[clientIndex])
        {
            if (request == "LIST UPS")
            {
                client.print("BEGIN LIST UPS\n");
                client.print("UPS qnapups \"" + ups_model + "\"\n");
                client.print("END LIST UPS\n");
            }
            else if (request.startsWith("LIST VAR qnapups"))
            {
                client.print("BEGIN LIST VAR qnapups\n");
                client.print("VAR qnapups battery.charge \"" + String(ups_charge) + "\"\n");
                client.print("VAR qnapups battery.charge.low \"" + String(ups_charge_low) + "\"\n"); // 电池电量低设定点
                client.print("VAR qnapups battery.runtime \"" + String(ups_runtime) + "\"\n");       // 电池运行时间
                client.print("VAR qnapups battery.voltage \"" + String(ups_voltage) + "\"\n");       // 电池电压
                client.print("VAR qnapups battery.type \"" + ups_type + "\"\n");                     // 电池化学成分 PbAc
                client.print("VAR qnapups driver.name \"" + ups_driver_name + "\"\n");
                client.print("VAR qnapups driver.parameter.port \"" + ups_driver_parameter_port + "\"\n");
                client.print("VAR qnapups driver.version \"" + ups_driver_version + "\"\n");
                client.print("VAR qnapups driver.version.data \"" + ups_driver_version_data + "\"\n");
                client.print("VAR qnapups driver.version.internal \"" + ups_driver_version_internal + "\"\n");
                client.print("VAR qnapups input.frequency \"" + String(ups_input_frequency) + "\"\n"); // 输入频率
                // client.print("VAR qnapups input.transfer.boost.low \"184.0\"\n");
                // client.print("VAR qnapups input.transfer.trim.high \"265.0\"\n");
                client.print("VAR qnapups input.transfer.high \"" + String(ups_input_transfer_high) + "\"\n");       // 高压转移
                client.print("VAR qnapups input.transfer.low \"" + String(ups_input_transfer_low) + "\"\n");         // 低压转移
                client.print("VAR qnapups input.voltage \"" + String(ups_input_voltage) + "\"\n");                   // 输入电压
                client.print("VAR qnapups output.current \"" + String(ups_output_current) + "\"\n");                 // 输出电流
                client.print("VAR qnapups output.frequency \"" + String(ups_output_frequency) + "\"\n");             // 输出频率
                client.print("VAR qnapups output.voltage \"" + String(ups_output_voltage) + "\"\n");                 // 输出电压
                client.print("VAR qnapups ups.delay.shutdown \"" + String(ups_delay_shutdown) + "\"\n");             // UPS关机延时
                client.print("VAR qnapups ups.delay.start \"" + String(ups_delay_start) + "\"\n");                   // 加载重启延时
                client.print("VAR qnapups ups.load \"" + String(ups_load) + "\"\n");                                 // 负载
                client.print("VAR qnapups ups.mfr \"" + ups_mfr + "\"\n");                                           // 制造商信息
                client.print("VAR qnapups ups.model \"" + ups_model + "\"\n");                                       // 设备型号
                client.print("VAR qnapups ups.power.nominal \"" + ups_power_nominal + "\"\n");                       // 标称功率
                client.print("VAR qnapups output.voltage.nominal \"" + String(ups_output_voltage_nominal) + "\"\n"); // 标称输出电压
                client.print("VAR qnapups device.mfr \"" + ups_device_mfr + "\"\n");                                 // 制造商信息
                client.print("VAR qnapups device.model \"" + ups_device_model + "\"\n");                             // 设备型号
                client.print("VAR qnapups device.type \"" + ups_device_type + "\"\n");                               //
                client.print("VAR qnapups outlet.id \"" + ups_outlet_id + "\"\n");                                   //
                client.print("VAR qnapups outlet.switchable \"" + ups_outlet_switchable + "\"\n");                   //
                client.print("VAR qnapups ups.serial \"" + ups_serial + "\"\n");                                     // 序列号
                client.print("VAR qnapups ups.status \"" + ups_status + "\"\n");                                     // UPS 状态（OL：在线 CHRG：充电 LB：电量不足 ）
                client.print("VAR qnapups ups.test.interval \"" + String(ups_test_interval) + "\"\n");               // 自检间隔
                client.print("VAR qnapups ups.test.result \"" + ups_test_result + "\"\n");                           // 自检结果 Done and OK
                client.print("END LIST VAR qnapups\n");
                client.flush(); // 确保数据发送
            }
            else if (request.startsWith("GET VAR qnapups "))
            {
                String varName = request.substring(18);
                if (varName == "battery.charge")
                {
                    client.println("VAR qnapups battery.charge \"90\"");
                }
                else if (varName == "battery.voltage")
                {
                    client.println("VAR qnapups battery.voltage \"230.0\"");
                }
                else if (varName == "battery.runtime")
                {
                    client.println("VAR qnapups battery.runtime \"3690\"");
                }
                else if (varName == "input.voltage")
                {
                    client.println("VAR qnapups input.voltage \"230.0\"");
                }
                else if (varName == "output.voltage")
                {
                    client.println("VAR qnapups output.voltage \"230.0\"");
                }
                else if (varName == "output.load")
                {
                    client.println("VAR qnapups output.load \"10\"");
                }
                else if (varName == "ups.status")
                {
                    client.println("VAR qnapups ups.status \"OL CHRG\"");
                }
                else if (varName == "ups.test.result")
                {
                    client.println("VAR qnapups ups.test.result \"Done and OK\"");
                }
                else
                {
                    client.println("ERR UNKNOWN-VAR");
                }
            }
            else if (request == "LOGOUT")
            {
                Serial.println("Client requested logout");
                client.println("OK Goodbye");
                delay(100);
                client.stop();
            }
            else
            {
                client.println("ERR UNKNOWN-COMMAND");
            }
        }
        else
        {
            client.println("ERR ACCESS-DENIED");
            client.stop();
        }
    }
}

void loop()
{
    // 处理新客户端连接
    WiFiClient newClient = nutServer.available();
    if (newClient)
    {
        Serial.println("New client attempting to connect...");

        // 查找空闲槽位
        for (int i = 0; i < MAX_CLIENTS; i++)
        {
            if (!clients[i] || !clients[i].connected()) // 发现空闲槽位
            {
                clients[i] = newClient;
                isAuthenticated[i] = false;
                authRequired[i] = false;
                authStartTime[i] = millis();
                Serial.print("Client connected at index ");
                Serial.println(i);
                break;
            }
        }
    }

    // 处理每个已连接的客户端
    for (int i = 0; i < MAX_CLIENTS; i++)
    {
        if (clients[i] && clients[i].connected())
        {
            nut_handleClient(i);
        }
        else if (clients[i])
        {
            Serial.print("Client disconnected at index ");
            Serial.println(i);
            clients[i].stop();
        }
    }

    // 超时检查，防止客户端卡住
    for (int i = 0; i < MAX_CLIENTS; i++)
    {
        if (authRequired[i] && !isAuthenticated[i] && millis() - authStartTime[i] > 10000)
        {
            clients[i].println("ERR ACCESS-DENIED");
            clients[i].stop();
        }
    }
}
